import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import skew, kurtosis
plt.rcParams["font.sans-serif"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 确保负号正确显示
# 加载数据
data = pd.read_csv('./boston.csv')

# 设置图片清晰度
plt.rcParams['figure.dpi'] = 300


# 计算统计指标
skewness = skew(data['MEDV'])
kurt = kurtosis(data['MEDV'])
std_dev = data['MEDV'].std()

# 创建一个新的图形和坐标轴
fig, ax = plt.subplots(figsize=(10, 6))

# 绘制直方图，分30个区间，叠加核密度估计曲线
n, bins, patches = ax.hist(data['MEDV'], bins=30, density=True, alpha=0.7, edgecolor='black')

# 给直方图添加渐变色
for patch, color in zip(patches, plt.cm.viridis(n / n.max())):
    patch.set_facecolor(color)

# 绘制核密度估计曲线
sns.kdeplot(data['MEDV'], ax=ax, color='r', linewidth=2)

# 标注均值和中位数的位置
mean_value = data['MEDV'].mean()
median_value = data['MEDV'].median()
ax.axvline(mean_value, color='r', linestyle='--', linewidth=2, label=f'均值: {mean_value:.2f}')
ax.axvline(median_value, color='r', linestyle='-.', linewidth=2, label=f'中位数: {median_value:.2f}')

# 突出显示MEDV>50的异常区间
for patch in patches:
    if patch.get_x() >= 50:
        patch.set_facecolor('r')

# 添加统计框
stats_text = f'偏度: {skewness:.2f}\n峰度: {kurt:.2f}\n标准差: {std_dev:.2f}'
ax.text(0.8, 0.9, stats_text, transform=ax.transAxes, bbox=dict(facecolor='white', edgecolor='black', alpha=0.7))

# 设置标题和坐标轴标签
ax.set_title('房价分布直方图')
ax.set_xlabel('房价 (MEDV)')
ax.set_ylabel('密度')
ax.legend()

# 显示图形
plt.show()